iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 8
0
自我挑戰組

網頁前端框架 Vue 3 從頭開始(重新挑戰)系列 第 8

vue3 Composition API 學習手冊-8 v-for為何要定義key呢?

  • 分享至 

  • xImage
  •  

講到了v-for和v-bind就不得不提key的這個屬性,主要就是要討論透過v-for所渲染的項目,在資料更新時會怎麼處理,若在v-for渲染的項目中“沒有”加入key屬性(如上面的範例),預設的行為是當數據順序改變時,vue會透過“就地更新(In-place patch)”的策略進行變更,也就是說Vue不會移動任何DOM元素來配合數據順序,只是就地去更新項目內容確保他們在每個索引位置正確的渲染。

透過上述的方式能夠增強網頁的效能,但有時候並沒有辦法達到我們期望的效果,我們透過下面的範例進行說明:

<div id="app">
    <h3>Please make your choice:</h3>
    <ul>
        <li v-for="item in state.names">
            {{ item.title }} : 
            <select>
                <option disabled value="" selected>Please select one</option>
                <option v-for="(item, index) in state.types" :value="item.value">{{ item.title }}</option>
            </select>
        </li>
    </ul>
    <p>
        <button @click="sortASC">Sort by Name ASC</button>
        <button @click="sortDESC">Sort by Name DESC</button>
    </p>
</div>
<script>
const { reactive } = Vue;
const app = {
    setup() {
        const state = reactive({
            names:[
                {title: "Vue", value: "Vue"},
                {title: "React", value: "React"},
                {title: "Angular", value: "Angular"},
                {title: "Laravel", value: "Laravel"},
                {title: "CakePHP", value: "CakePHP"},
                {title: "Django", value: "Django"},
            ],
            types:[
                {title: "Frontend", value: "Frontend"},
                {title: "Backend", value: "Backend"},
            ],
        })
        function sortASC() {
            state.names = state.names.sort(function (a, b) {
                return a.title > b.title ? 1 : -1;
            });
        }
        function sortDESC() {
            state.names = state.names.sort(function (a, b) {
                return b.title > a.title ? 1 : -1;
            });
        }
        return { state, sortASC, sortDESC};
    }
}
const myVue = Vue.createApp(app).mount("#app");
</script>

大家可以先想像一下這是一個小測驗的網頁,在頁面中有六個選項,選項旁邊有個下拉選單讓使用者挑選正確答案,然後比較重要的是下面有兩個按鈕,可以讓數列按字母重新排序,當使用者選完旁邊的選項之後,再按下重新排序的按鈕,你就會發現,雖然數據重新渲染,但因為沒有更新DOM的順序,所以會發生項目還使用者選取的結果對不起來的問題!

範例檔

解決方案就是在需要透過v-for渲染的tag中加入key屬性,也就是只要更新上面HTML的第4行如下:

<li v-for="item in state.names" :key="item.title">

就可以得到下面這個範例的結果囉!範例檔

要注意給的key值是不能有重複的,否則頁面會發生錯誤,也不建議使用index當做Key值,因為若爾後插入值在數列中,就會造成渲染錯誤,大家可以依據自己在頁面中的需求,來考量是否需要在v-for中加入key屬性(當然很多人選擇無腦加)。

v-for 參數


除了能透過Value來產生數列外,也可以透過以下的方式來取得物件的Key與Index值:

<div id="app">
    <ul>
        <li v-for="(value, name, index) in state.frameworks">
            {{ index + 1 }}. {{ name }} - {{ value }}
        </li>
    </ul>
</div>
<script>
const { reactive } = Vue;
const app = {
    setup() {
        const state = reactive({
            frameworks: {
                Vue: "Frontend",
                React: "Frontend",
                Angular: "Frontend",
                Laravel: "Backend",
                CakePHP: "Backend",
                Django: "Backend",
            },
        })
        return { state };
    }
}
const myVue = Vue.createApp(app).mount("#app");
</script>

好啦!今天的文章就先到這裡,明天繼續跟大家介紹vue中方便又好用的功能。


上一篇
vue3 Composition API 學習手冊-7 清單渲染
下一篇
vue3 Composition API 學習手冊-9 計算屬性
系列文
網頁前端框架 Vue 3 從頭開始(重新挑戰)30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言